
#include "memoryData.h"
#include "boost/thread.hpp"

using namespace std;


namespace mem {

vector<int> lastDataLists[INDEX_MAX]; // 上次取数数据列表
int  lastIndex[INDEX_MAX]; // 上次取数的m绝对值




boost::mutex _x05_mutex; // X05 访问锁

int iMax_X05 = 0, iX05 = 0; // 当前最大处理X05值、当前最大连续处理X05值
int iLastMappingX05 = 0; // 最后增量保存X05值
vector<SMISS> missingList;


#include "Comparator.cpp.h" //move _init query & match functor to this file
#include "MemoryDataInitDeinit.cpp.h"


Orders * orders = nullptr;
ContractNotes * contractNotes = nullptr;
DeliveryOrders * deliveryOrders = nullptr;
MiddleOrders * middleOrders = nullptr;
DeliveryContractNotes * deliveryContractNotes = nullptr;
Notices * notices = nullptr;

#include "SearchSort.cpp.h"


static bool isInited = false;
int initMemoryData(int maxOrderCount, int maxMatchCount){
    if(maxOrderCount <= 0 || maxMatchCount <= 0){
        logs(error_, "maxOrderCount & maxMatchCount must be >= 1");
        return -1;
    }

	if (isInited == false) {
        orders = new Orders(maxOrderCount);

        contractNotes = new ContractNotes(maxMatchCount);

        deliveryOrders = new DeliveryOrders(MAX_JIAOGE_COUNT); 

        middleOrders = new MiddleOrders(MAX_ZHONGLICANG_COUNT);

        deliveryContractNotes = new DeliveryContractNotes(MAX_JG_ZLC_CHENGJIAODAN_COUNT);

		notices = new Notices(MAX_GONGGAO_COUNT);

        if(!__isOpInited()){
            __initOp();
        }

		isInited = true;
	}
	return 0;

}
int deinitMemoryData() {
	if (isInited == true) {
		if(notices != nullptr){
			delete notices;
			notices = nullptr;
		}

        if(deliveryContractNotes != nullptr){
            delete deliveryContractNotes;
            deliveryContractNotes = nullptr;
        }

        if(middleOrders != nullptr){
            delete middleOrders;
            middleOrders = nullptr;
        }
		
        if(deliveryOrders != nullptr){
            delete deliveryOrders;
            deliveryOrders = nullptr;
        }
        if(contractNotes != nullptr){
            delete contractNotes;
            contractNotes = nullptr;
        }

        if(orders != nullptr){
            delete orders;
            orders = nullptr;
        }

		isInited = false;
	}
	return 0;
}
int getMaxOrderCount(){
    return orders->maxCount();
}
int getMaxMatchCount(){
    return contractNotes->maxCount();
}

// 获取首地址
//void* getPointer(int index) {
//	if (index >= INDEX_MAX)
//		return NULL;
//	switch (index) {
//		case INDEX_BAODAN:
//			return reinterpret_cast<void*>(orders->array());
//		case INDEX_JIAOGE:
//			return reinterpret_cast<void*>(deliveryOrders->array());
//		case INDEX_ZHONGLICANG:
//			return reinterpret_cast<void*>(middleOrders->array());
//		case INDEX_CHENGJIAODAN:
//			return reinterpret_cast<void*>(contractNotes->array());
//		case INDEX_JG_CHENGJIAODAN:
//		case INDEX_ZLC_CHENGJIAODAN:
//			return reinterpret_cast<void*>(deliveryContractNotes->array());
//		case INDEX_GONGGAO:
//			return reinterpret_cast<void*>(notices->array());
//		default:
//			return NULL;
//	}
//}

static void __lock_shared_all(){
	orders->mutex().lock_shared();
	deliveryOrders->mutex().lock_shared();
	middleOrders->mutex().lock_shared();

	contractNotes->mutex().lock_shared();
	deliveryContractNotes->mutex().lock_shared();
	notices->mutex().lock_shared();
}
static void __lock_exclude_all(){
	orders->mutex().lock();
	deliveryOrders->mutex().lock();
	middleOrders->mutex().lock();

	contractNotes->mutex().lock();
	deliveryContractNotes->mutex().lock();
	notices->mutex().lock();
}
static void __unlock_shared_all(){
	orders->mutex().unlock_shared();
	deliveryOrders->mutex().unlock_shared();
	middleOrders->mutex().unlock_shared();

	contractNotes->mutex().unlock_shared();
	deliveryContractNotes->mutex().unlock_shared();
	notices->mutex().unlock_shared();
}
static void __unlock_exclude_all(){
	orders->mutex().unlock();
	deliveryOrders->mutex().unlock();
	middleOrders->mutex().unlock();

	contractNotes->mutex().unlock();
	deliveryContractNotes->mutex().unlock();
	notices->mutex().unlock();
}


// 重置所有数据（预留函数）
int resetMemory() {
	int ret = 0;
	__lock_exclude_all(); // 锁定全部内存数组操作

	iLastMappingX05 = 0;
	iMax_X05 = 0;
	iX05 = 0;
	missingList.clear();
	for (int i = 0; i < INDEX_MAX; i++) {
		lastDataLists[i].clear();
		lastIndex[i] = 0;
	}

	if(orders == nullptr){
		ret = -1;
		goto errOut;
	}
	orders->reset();

	if(contractNotes == nullptr){
		ret = -1;
		goto errOut;
	}
	contractNotes->reset();

	if(deliveryOrders == nullptr){ 
		ret = -1;
		goto errOut;
	}
	deliveryOrders->reset();

	if(middleOrders == nullptr){
		ret = -1;
		goto errOut;
	}
	middleOrders->reset();

	if(deliveryContractNotes == nullptr){
		ret = -1;
		goto errOut;
	}
	deliveryContractNotes->reset();

	if(notices == nullptr){
		ret = -1;
		goto errOut;
	}
	notices->reset();

	__unlock_exclude_all();
	return 0;

errOut:
	__unlock_exclude_all();
	return ret;
}


// 更新X05值（主体逻辑为保存接收的连续计数到最大X05值，但对于单次跳号过大或长时间漏号给予特殊处理）
void _update_x05(int x05) {
	_x05_mutex.lock();
	bool deleted = false;
	for (vector<SMISS>::iterator it = missingList.begin(); it != missingList.end(); it++) {
		it->times++;
		// 删除当前值、如果计数超时一定值则将其从当前列表中删除
		if (it->value == x05 || it->times >= MAX_MISSING_TIMES) {
			deleted = true;
			it = missingList.erase(it);
			it--; // 注意，这里做了erase之后需要恢复指针再操作，后续可能还有需要删除的数据；
		}
	}
	// 当前X05与已接收最大X05值不连续时，插入漏号记录至列表
	if (x05 > iMax_X05 + 1) {
		// 如果当前X05数值跳跃超过一定值则重置
		if (x05 - iMax_X05 >= MAX_MISSING_COUNT) {
			missingList.clear();
			iMax_X05 = x05;
			iX05 = x05;
		}
		else {
			// 插入本次所漏的X05值（初始计数为0）
			for (int i = iMax_X05 + 1; i < x05; i++) {
				SMISS miss;
				miss.value = i;
				miss.times = 1;
				missingList.push_back(miss);
			}
			iMax_X05 = x05;
		}
	}
	else if (x05 == iMax_X05 + 1) {
		if (iX05 == iMax_X05)
			iX05 = x05;
		iMax_X05 = x05;
	}
	if (deleted) {
		// 如果有发生从漏号列表中删除序号，则尝试检查是否有X05新的连续值
		bool flag = true;
		for (; iX05 < iMax_X05; iX05++) {
			for (vector<SMISS>::iterator it = missingList.begin(); it != missingList.end(); it++) {
				if (it->value == iX05 + 1)
					flag = false;
			}
			if (!flag)
				break;
		}
	}
	// 注意，以下被注释代码为debug使用，请勿删除
	//std:cout << "<--" << iX05 << "\t" << iMax_X05 << "\t" << missingList.size() << "\n";
	//for(int i=0;i<missingList.size();i++)
	//    std::cout << missingList.at(i).value << "(" << missingList.at(i).times <<")\t";
	//std::cout << "-->\n";
	_x05_mutex.unlock();
}

// 获取对应序号的内存数组值的指针
void* dataPointer(int index, size_t dataIdx) {
	if (index == INDEX_BAODAN)
		return orders->data(dataIdx);
	else if (index == INDEX_JIAOGE)
		return deliveryOrders->data(dataIdx);
	else if (index == INDEX_ZHONGLICANG)
		return middleOrders->data(dataIdx);
	else if (index == INDEX_CHENGJIAODAN)
		return contractNotes->data(dataIdx);
	else if (index == INDEX_JG_CHENGJIAODAN || index == INDEX_ZLC_CHENGJIAODAN)
		return deliveryContractNotes->data(dataIdx);
	else if (index == INDEX_GONGGAO)
		return notices->data(dataIdx);
	return NULL;
}


// arary 
// index  & filter
// match function 
// quick_sort, binary_search, 
//

// 插入或更新数据
int insertOrUpdateData(int index, void* data) {
	// 如果报单、交割报单、中立仓报单才会更新逻辑；各种成交单都没有，所以找到相同时不处理
	if (index == INDEX_BAODAN) {
        orders->insertOrUpdate(data);
	}
	else if (index == INDEX_JIAOGE) {
		deliveryOrders->mutex().lock();
		SJIAOGE* jiaoge = (SJIAOGE*)data;
		jiaoge->iT12_part = jiaoge->iT12 >= NIGHT_BEGIN_TIME ? jiaoge->iT12 - NIGHT_BEGIN_TIME : jiaoge->iT12 + DAY_BEGIN_OFFSET;
		jiaoge->sM20_part = jiaoge->iM20 / 100; // 席位号前4位的会员代码
		int idx = _binarysearch(INDEX_JIAOGE, deliveryOrders->count()
				, deliveryOrders->idx_jiaoge_O00(), deliveryOrders->count()
				, data, FIELD_JIAOGE_NONE
				, deliveryOrders->count() >= deliveryOrders->maxCount() ? MODE_NONE : MODE_INSERT);
		if (idx >= 0) {
			if (jiaoge->iX05 > deliveryOrders->data(deliveryOrders->idx_jiaoge_O00()[idx])->iX05) {
				bool flag1 = deliveryOrders->bIsFiltered() && _matchfilter_jiaoge(&deliveryOrders->filter_jiaoge(), deliveryOrders->data(deliveryOrders->idx_jiaoge_O00()[idx]));
				memcpy(deliveryOrders->data(deliveryOrders->idx_jiaoge_O00()[idx]), jiaoge, sizeof(SJIAOGE));
				// 数据发生更新、重新判断是否符合筛选条件；如果符合要从对应筛选索引中删除
				if (deliveryOrders->bIsFiltered()) {
					bool flag2 = _matchfilter_jiaoge(&deliveryOrders->filter_jiaoge(), jiaoge);
					if (flag1 && !flag2) {
						_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount(), deliveryOrders->idx_filter_jiaoge_O00(), deliveryOrders->idx_jiaoge_O00()[idx], NULL, FIELD_JIAOGE_NONE, MODE_DELETE);
						_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount(), deliveryOrders->idx_filter_jiaoge_T12(), deliveryOrders->idx_jiaoge_O00()[idx], NULL, FIELD_JIAOGE_iT12_part, MODE_DELETE);
						deliveryOrders->iFilterCount() --;
					}
					else if (!flag1 && flag2) {
						_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount(), deliveryOrders->idx_filter_jiaoge_O00(), deliveryOrders->idx_jiaoge_O00()[idx], data, FIELD_JIAOGE_NONE, MODE_INSERT);
						_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount(), deliveryOrders->idx_filter_jiaoge_T12(), deliveryOrders->idx_jiaoge_O00()[idx], data, FIELD_JIAOGE_iT12_part, MODE_INSERT);
						deliveryOrders->iFilterCount() ++;
					}
				}
			}
		}
		else {
			// 插入数据（判断是否超过最大值作越界容错/丢弃，注意如果换成从0开始覆盖算法，则需要从原各索引中找到覆盖序号删除并重新排序插入）
			if (deliveryOrders->count() >= deliveryOrders->maxCount()) {
				logs(error_, "deliveryOrders' count has been equal to the MAX_JIAOGE_COUNT, orderNo:" + to_string(jiaoge->iO00));
				deliveryOrders->mutex().unlock();
				return -1;
			}
			memcpy(deliveryOrders->data(deliveryOrders->count()), jiaoge, sizeof(SJIAOGE));
			// 更新其它索引以及筛选索引
			_binarysearch(INDEX_JIAOGE, deliveryOrders->count()
					, deliveryOrders->idx_jiaoge_T12(), deliveryOrders->count()
					, data, FIELD_JIAOGE_iT12_part, MODE_INSERT);
			if (deliveryOrders->bIsFiltered() && _matchfilter_jiaoge(&deliveryOrders->filter_jiaoge(), jiaoge)) {
				_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount()
						, deliveryOrders->idx_filter_jiaoge_O00(), deliveryOrders->count()
						, data, FIELD_JIAOGE_NONE, MODE_INSERT);
				_binarysearch(INDEX_JIAOGE, deliveryOrders->iFilterCount()
						, deliveryOrders->idx_filter_jiaoge_T12(), deliveryOrders->count()
						, data, FIELD_JIAOGE_iT12_part, MODE_INSERT);
				deliveryOrders->iFilterCount() ++;
			}
			deliveryOrders->count() ++ ;
		}
		// 更新X05值
		_update_x05(jiaoge->iX05);
		deliveryOrders->mutex().unlock();
	}
	else if (index == INDEX_ZHONGLICANG) {
		middleOrders->mutex().lock();
		SZHONGLICANG* zhonglicang = (SZHONGLICANG*)data;
		zhonglicang->iT12_part = zhonglicang->iT12 >= NIGHT_BEGIN_TIME ? zhonglicang->iT12 - NIGHT_BEGIN_TIME : zhonglicang->iT12 + DAY_BEGIN_OFFSET;
		zhonglicang->sM20_part = zhonglicang->iM20 / 100; // 席位号前4位的会员代码
		int idx = _binarysearch(INDEX_ZHONGLICANG, middleOrders->count()
				, middleOrders->idx_zhonglicang_O00(), middleOrders->count()
				, data, FIELD_ZHONGLICANG_NONE
				, middleOrders->count() >= middleOrders->maxCount() ? MODE_NONE : MODE_INSERT);
		if (idx >= 0) {
			if (zhonglicang->iX05 > middleOrders->data(middleOrders->idx_zhonglicang_O00()[idx])->iX05) {
				bool flag1 = middleOrders->bIsFiltered()
					&& _matchfilter_zhonglicang(&middleOrders->filter_zhonglicang(), middleOrders->data(middleOrders->idx_zhonglicang_O00()[idx]));
				memcpy(middleOrders->data(middleOrders->idx_zhonglicang_O00()[idx]), zhonglicang, sizeof(SZHONGLICANG));
				// 数据发生更新、重新判断是否符合筛选条件；如果符合要从对应筛选索引中删除
				if (middleOrders->bIsFiltered()) {
					bool flag2 = _matchfilter_zhonglicang(&middleOrders->filter_zhonglicang(), zhonglicang);
					if (flag1 && !flag2) {
						_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
								, middleOrders->idx_filter_zhonglicang_O00(), middleOrders->idx_zhonglicang_O00()[idx]
								, NULL, FIELD_ZHONGLICANG_NONE, MODE_DELETE);
						_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
								, middleOrders->idx_filter_zhonglicang_T12(), middleOrders->idx_zhonglicang_O00()[idx]
								, NULL, FIELD_ZHONGLICANG_iT12_part, MODE_DELETE);
						middleOrders->iFilterCount() --;
					}
					else if (!flag1 && flag2) {
						_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
								, middleOrders->idx_filter_zhonglicang_O00(), middleOrders->idx_zhonglicang_O00()[idx]
								, data, FIELD_ZHONGLICANG_NONE, MODE_INSERT);
						_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
								, middleOrders->idx_filter_zhonglicang_T12(), middleOrders->idx_zhonglicang_O00()[idx]
								, data, FIELD_ZHONGLICANG_iT12_part, MODE_INSERT);
						middleOrders->iFilterCount() ++;
					}
				}
			}
		}
		else {
			// 插入数据（判断是否超过最大值作越界容错/丢弃，注意如果换成从0开始覆盖算法，则需要从原各索引中找到覆盖序号删除并重新排序插入）
			if (middleOrders->count() >= middleOrders->maxCount()) {
				logs(error_, "middleApplyOrders' count has been equal to the MAX_ZHONGLICANG_COUNT, orderNo:" + to_string(zhonglicang->iO00));
				middleOrders->mutex().unlock();
				return -1;
			}
			memcpy(middleOrders->data(middleOrders->count()), zhonglicang, sizeof(SZHONGLICANG));
			// 更新其它索引以及筛选索引
			_binarysearch(INDEX_ZHONGLICANG, middleOrders->count()
					, middleOrders->idx_zhonglicang_T12(), middleOrders->count()
					, data, FIELD_ZHONGLICANG_iT12_part, MODE_INSERT);
			if (middleOrders->bIsFiltered()
					&& _matchfilter_zhonglicang(&middleOrders->filter_zhonglicang(), zhonglicang)) {
				_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
						, middleOrders->idx_filter_zhonglicang_O00(), middleOrders->count()
						, data, FIELD_ZHONGLICANG_NONE, MODE_INSERT);
				_binarysearch(INDEX_ZHONGLICANG, middleOrders->iFilterCount()
						, middleOrders->idx_filter_zhonglicang_T12(), middleOrders->count()
						, data, FIELD_ZHONGLICANG_iT12_part, MODE_INSERT);
				middleOrders->iFilterCount() ++;
			}
			++ middleOrders->count();
		}
		// 更新X05值
		_update_x05(zhonglicang->iX05);
		middleOrders->mutex().unlock();
	}
	else if (index == INDEX_CHENGJIAODAN) {
		contractNotes->mutex().lock();
		SCHENGJIAODAN* chengjiaodan = (SCHENGJIAODAN*)data;
		chengjiaodan->iO62_part = chengjiaodan->iO62 >= NIGHT_BEGIN_TIME ? chengjiaodan->iO62 - NIGHT_BEGIN_TIME : chengjiaodan->iO62 + DAY_BEGIN_OFFSET;
		chengjiaodan->sM20_part = chengjiaodan->iM20 / 100; // 席位号前4位的会员代码
		int idx = _binarysearch(INDEX_CHENGJIAODAN, contractNotes->count()
				, contractNotes->idx_chengjiaodan_O60_O02(), contractNotes->count()
				, data, FIELD_CHENGJIAODAN_NONE
				, contractNotes->count() >= contractNotes->maxCount() ? MODE_NONE : MODE_INSERT);
		// 注意，成交单没有更新逻辑
		if (idx < 0) {
			// 插入数据（判断是否超过最大值作越界容错/丢弃，注意如果换成从0开始覆盖算法，则需要从原各索引中找到覆盖序号删除并重新排序插入）
			if (contractNotes->count() >= contractNotes->maxCount()) {
				logs(error_, "MatchOrders' count has been equal to the max_match_cnt, matchNo:" + string(chengjiaodan->sO60) + " buyOrSell:" + chengjiaodan->cO02);
				contractNotes->mutex().unlock();
				return -1;
			}
			memcpy(contractNotes->data(contractNotes->count()), chengjiaodan, sizeof(SCHENGJIAODAN));
			// 更新其它索引以及筛选索引
			_binarysearch(INDEX_CHENGJIAODAN, contractNotes->count()
					, contractNotes->idx_chengjiaodan_O62(), contractNotes->count()
					, data, FIELD_CHENGJIAODAN_iO62_part, MODE_INSERT);
			if (contractNotes->bIsFiltered()
					&& _matchfilter_chengjiaodan(&contractNotes->filter_chengjiaodan(), chengjiaodan)) {
				_binarysearch(INDEX_CHENGJIAODAN, contractNotes->iFilterCount()
						, contractNotes->idx_filter_chengjiaodan_O60_O02(), contractNotes->count()
						, data, FIELD_CHENGJIAODAN_NONE, MODE_INSERT);
				_binarysearch(INDEX_CHENGJIAODAN, contractNotes->iFilterCount()
						, contractNotes->idx_filter_chengjiaodan_O62(), contractNotes->count()
						, data, FIELD_CHENGJIAODAN_iO62_part, MODE_INSERT);
				contractNotes->iFilterCount() ++;
			}
			++ contractNotes->count();
		}
		// 更新X05值
		_update_x05(chengjiaodan->iX05);
		contractNotes->mutex().unlock();
	}
	else if (index == INDEX_JG_CHENGJIAODAN || index == INDEX_ZLC_CHENGJIAODAN) {
		deliveryContractNotes->mutex().lock();
		SJG_ZLC_CHENGJIAODAN* jg_zlc_chengjiaodan = (SJG_ZLC_CHENGJIAODAN*)data;
		jg_zlc_chengjiaodan->iO62_part = jg_zlc_chengjiaodan->iO62 >= NIGHT_BEGIN_TIME ? jg_zlc_chengjiaodan->iO62 - NIGHT_BEGIN_TIME : jg_zlc_chengjiaodan->iO62 + DAY_BEGIN_OFFSET;
		jg_zlc_chengjiaodan->sM20_part = jg_zlc_chengjiaodan->iM20 / 100; // 席位号前4位的会员代码
		int idx = _binarysearch(INDEX_JG_CHENGJIAODAN, deliveryContractNotes->count()
				, deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02(), deliveryContractNotes->count()
				, data, FIELD_JG_ZLC_CHENGJIAODAN_NONE
				, deliveryContractNotes->count() >= deliveryContractNotes->maxCount() ? MODE_NONE : MODE_INSERT);
		// 注意，交割、中立仓成交单没有更新逻辑
		if (idx < 0) {
			// 插入数据（判断是否超过最大值作越界容错/丢弃，注意如果换成从0开始覆盖算法，则需要从原各索引中找到覆盖序号删除并重新排序插入）
			if (deliveryContractNotes->count() >= deliveryContractNotes->maxCount()) {
				logs(error_, "DeliveryMatchOrders' count has been equal to the MAX_JG_ZLC_CHENGJIAODAN_COUNT, matchNo:" + string(jg_zlc_chengjiaodan->sO60) + " buyOrSell:" + jg_zlc_chengjiaodan->cO02 + " middleFlag:" + jg_zlc_chengjiaodan->cO05);
				deliveryContractNotes->mutex().unlock();
				return -1;
			}
			memcpy(deliveryContractNotes->data(deliveryContractNotes->count()), jg_zlc_chengjiaodan, sizeof(SJG_ZLC_CHENGJIAODAN));
			// 更新筛选索引
			if (_matchfilter_jg_zlc_chengjiaodan(&deliveryContractNotes->filter_jg_chengjiaodan(), jg_zlc_chengjiaodan)) {
				_binarysearch(INDEX_JG_CHENGJIAODAN, deliveryContractNotes->iFilterCountDelivery()
						, deliveryContractNotes->idx_filter_jg_chengjiaodan_O60_O02(), deliveryContractNotes->count()
						, data, FIELD_JG_ZLC_CHENGJIAODAN_NONE, MODE_INSERT);
				_binarysearch(INDEX_JG_CHENGJIAODAN, deliveryContractNotes->iFilterCountDelivery()
						, deliveryContractNotes->idx_filter_jg_chengjiaodan_O62(), deliveryContractNotes->count()
						, data, FIELD_JG_ZLC_CHENGJIAODAN_iO62_part, MODE_INSERT);
				deliveryContractNotes->iFilterCountDelivery() ++;
			}
			if (_matchfilter_jg_zlc_chengjiaodan(&deliveryContractNotes->filter_zlc_chengjiaodan(), jg_zlc_chengjiaodan)) {
				_binarysearch(INDEX_ZLC_CHENGJIAODAN, deliveryContractNotes->iFilterCountMiddle()
						, deliveryContractNotes->idx_filter_zlc_chengjiaodan_O60_O02(), deliveryContractNotes->count()
						, data, FIELD_JG_ZLC_CHENGJIAODAN_NONE, MODE_INSERT);
				_binarysearch(INDEX_ZLC_CHENGJIAODAN, deliveryContractNotes->iFilterCountMiddle()
						, deliveryContractNotes->idx_filter_zlc_chengjiaodan_O62(), deliveryContractNotes->count()
						, data, FIELD_JG_ZLC_CHENGJIAODAN_iO62_part, MODE_INSERT);
				deliveryContractNotes->iFilterCountMiddle() ++;
			}
			deliveryContractNotes->count() ++ ;
		}
		// 更新X05值
		_update_x05(jg_zlc_chengjiaodan->iX05);
		deliveryContractNotes->mutex().unlock();
	}
	else if (index == INDEX_GONGGAO) {
		notices->mutex().lock();
		SGONGGAO* gonggao = (SGONGGAO*)data;
		int idx = _binarysearch(INDEX_GONGGAO, notices->count()
				, notices->idx_gonggao_T80(), notices->count()
				, data, FIELD_GONGGAO_NONE
				, notices->count() >= notices->maxCount() ? MODE_NONE : MODE_INSERT);
		if (idx < 0) {
			// 插入数据（判断是否超过最大值作越界容错/丢弃，注意如果换成从0开始覆盖算法，则需要从原各索引中找到覆盖序号删除并重新排序插入）
			if (notices->count() >= notices->maxCount()){
				notices->mutex().unlock();
				return -1;
			}
			memcpy(notices->data(notices->count()), gonggao, sizeof(SGONGGAO));
			notices->count() ++ ;
		}
		// 更新X05值
		_update_x05(gonggao->iX05);
		notices->mutex().unlock();
	}
	else{
		return -1;
	}
	return 0;
}
// 获取记录总数
int getCount(int index) {
	switch(index){
		case INDEX_GONGGAO:
			return notices->count();
		case INDEX_JG_CHENGJIAODAN:
			return deliveryContractNotes->iFilterCountDelivery();
		case INDEX_ZLC_CHENGJIAODAN:
			return deliveryContractNotes->iFilterCountMiddle();
		case INDEX_BAODAN:
			return orders->bIsFiltered() ? orders->iFilterCount() : orders->count();
		case INDEX_JIAOGE:
			return deliveryOrders->bIsFiltered() ? deliveryOrders->iFilterCount() : deliveryOrders->count();
		case INDEX_ZHONGLICANG:
			return middleOrders->bIsFiltered() ? middleOrders->iFilterCount() : middleOrders->count();
		case INDEX_CHENGJIAODAN:
			return contractNotes->bIsFiltered() ? contractNotes->iFilterCount() : contractNotes->count();
		default:
			logs(error_, "get Count unkown index");
		break;
	}
	return -1;
}

// 设置筛选条件
int setFilter(int index, void* data) {
	// 注意这里虽然有更新索引，但因为肯定不与insertOrUpdate冲突，所以需要外部保证同一时间段只有会独立调用该函数
	if (index == INDEX_BAODAN) {
		orders->mutex().lock_shared();
		lastDataLists[index].clear();
		lastIndex[index] = 0;

		SFILTER_BAODAN* f = (SFILTER_BAODAN*)data;
		if (f->cI10 == orders->filter_baodan().cI10 && f->cO09 == orders->filter_baodan().cO09 && f->cO15 == orders->filter_baodan().cO15 && f->iM20 == orders->filter_baodan().iM20 && f->iM30 == orders->filter_baodan().iM30){
			orders->mutex().unlock_shared();
			return 0;
		}
		else {
			orders->filter_baodan().cI10 = f->cI10;
			orders->filter_baodan().cO09 = f->cO09;
			orders->filter_baodan().cO15 = f->cO15;
			orders->filter_baodan().iM20 = f->iM20;
			orders->filter_baodan().iM30 = f->iM30;
			if (f->cI10 == -1 && f->cO09 == -1 && f->cO15 == -1 && f->iM20 == -1 && f->iM30 == -1)
				orders->bIsFiltered(false);
			else {
				orders->bIsFiltered(true);
				// 使用全量索引进行筛选判断直接生成筛选索引
				orders->_index_mutexs().lock();
				orders->iFilterCount() = 0;
				for (int i = 0, j = 0; i < orders->count(); i++) {
					if (_matchfilter_baodan(f, orders->data(orders->idx_baodan_O00()[i]))) {
						orders->idx_filter_baodan_O00()[j] = orders->idx_baodan_O00()[i];
						j++;
						orders->iFilterCount() ++;
					}
				}
				for (int i = 0, j = 0; i < orders->count(); i++) {
					if (_matchfilter_baodan(f, orders->data(orders->idx_baodan_T12()[i]))) {
						orders->idx_filter_baodan_T12()[j] = orders->idx_baodan_T12()[i];
						j++;
					}
				}
				orders->_index_mutexs().unlock();
			}
		}
		orders->mutex().unlock_shared();
		return 0;
	}
	else if (index == INDEX_JIAOGE) {
		deliveryOrders->mutex().lock_shared();

		lastDataLists[index].clear();
		lastIndex[index] = 0;

		SFILTER_JIAOGE* f = (SFILTER_JIAOGE*)data;
		if (f->cI10 == deliveryOrders->filter_jiaoge().cI10 && f->cO09 == deliveryOrders->filter_jiaoge().cO09 && f->cO15 == deliveryOrders->filter_jiaoge().cO15 && f->iM20 == deliveryOrders->filter_jiaoge().iM20 && f->iM30 == deliveryOrders->filter_jiaoge().iM30){
			deliveryOrders->mutex().unlock_shared();
			return 0;
		}
		else {
			deliveryOrders->filter_jiaoge().cI10 = f->cI10;
			deliveryOrders->filter_jiaoge().cO09 = f->cO09;
			deliveryOrders->filter_jiaoge().cO15 = f->cO15;
			deliveryOrders->filter_jiaoge().iM20 = f->iM20;
			deliveryOrders->filter_jiaoge().iM30 = f->iM30;
			if (f->cI10 == -1 && f->cO09 == -1 && f->cO15 == -1 && f->iM20 == -1 && f->iM30 == -1)
				deliveryOrders->bIsFiltered(false);
			else {
				deliveryOrders->bIsFiltered(true);
				// 使用全量索引进行筛选判断直接生成筛选索引
				deliveryOrders->_index_mutexs().lock();
				deliveryOrders->iFilterCount() = 0;
				for (int i = 0, j = 0; i < deliveryOrders->count(); i++) {
					if (_matchfilter_jiaoge(f, deliveryOrders->data(deliveryOrders->idx_jiaoge_O00()[i]))) {
						deliveryOrders->idx_filter_jiaoge_O00()[j] = deliveryOrders->idx_jiaoge_O00()[i];
						j++;
						deliveryOrders->iFilterCount() ++;
					}
				}
				for (int i = 0, j = 0; i < deliveryOrders->count(); i++) {
					if (_matchfilter_jiaoge(f, deliveryOrders->data(deliveryOrders->idx_jiaoge_T12()[i]))) {
						deliveryOrders->idx_filter_jiaoge_T12()[j] = deliveryOrders->idx_jiaoge_T12()[i];
						j++;
					}
				}
				deliveryOrders->_index_mutexs().unlock();
			}
		}
		deliveryOrders->mutex().unlock_shared();
		return 0;
	}
	else if (index == INDEX_ZHONGLICANG) {
		middleOrders->mutex().lock_shared();
		lastDataLists[index].clear();
		lastIndex[index] = 0;

		SFILTER_ZHONGLICANG* f = (SFILTER_ZHONGLICANG*)data;
		if (f->cI10 == middleOrders->filter_zhonglicang().cI10 && f->cO09 == middleOrders->filter_zhonglicang().cO09 && f->cO15 == middleOrders->filter_zhonglicang().cO15 && f->iM20 == middleOrders->filter_zhonglicang().iM20 && f->iM30 == middleOrders->filter_zhonglicang().iM30){
			middleOrders->mutex().unlock_shared();
			return 0;
		}
		else {
			middleOrders->filter_zhonglicang().cI10 = f->cI10;
			middleOrders->filter_zhonglicang().cO09 = f->cO09;
			middleOrders->filter_zhonglicang().cO15 = f->cO15;
			middleOrders->filter_zhonglicang().iM20 = f->iM20;
			middleOrders->filter_zhonglicang().iM30 = f->iM30;
			if (f->cI10 == -1 && f->cO09 == -1 && f->cO15 == -1 && f->iM20 == -1 && f->iM30 == -1)
				middleOrders->bIsFiltered(false);
			else {
				middleOrders->bIsFiltered(true);
				// 使用全量索引进行筛选判断直接生成筛选索引
				middleOrders->_index_mutexs().lock();
				middleOrders->iFilterCount() = 0;
				for (int i = 0, j = 0; i < middleOrders->count(); i++) {
					if (_matchfilter_zhonglicang(f, middleOrders->data(middleOrders->idx_zhonglicang_O00()[i]))) {
						middleOrders->idx_filter_zhonglicang_O00()[j] = middleOrders->idx_zhonglicang_O00()[i];
						j++;
						middleOrders->iFilterCount() ++;
					}
				}
				for (int i = 0, j = 0; i < middleOrders->count(); i++) {
					if (_matchfilter_zhonglicang(f, middleOrders->data(middleOrders->idx_zhonglicang_T12()[i]))) {
						middleOrders->idx_filter_zhonglicang_T12()[j] = middleOrders->idx_zhonglicang_T12()[i];
						j++;
					}
				}
				middleOrders->_index_mutexs().unlock();
			}
		}
		middleOrders->mutex().unlock_shared();
		return 0;
	}
	else if (index == INDEX_CHENGJIAODAN) {
		contractNotes->mutex().lock_shared();
		lastDataLists[index].clear();
		lastIndex[index] = 0;

		SFILTER_CHENGJIAODAN* f = (SFILTER_CHENGJIAODAN*)data;
		if (f->cI10 == contractNotes->filter_chengjiaodan().cI10 && f->iM20 == contractNotes->filter_chengjiaodan().iM20 && f->iM30 == contractNotes->filter_chengjiaodan().iM30){
			contractNotes->mutex().unlock_shared();
			return 0;
		}
		else {
			contractNotes->filter_chengjiaodan().cI10 = f->cI10;
			contractNotes->filter_chengjiaodan().iM20 = f->iM20;
			contractNotes->filter_chengjiaodan().iM30 = f->iM30;
			if (f->cI10 == -1 && f->iM20 == -1 && f->iM30 == -1)
				contractNotes->bIsFiltered(false);
			else {
				contractNotes->bIsFiltered(true);
				// 使用全量索引进行筛选判断直接生成筛选索引
				contractNotes->_index_mutexs().lock();
				contractNotes->iFilterCount() = 0;
				for (int i = 0, j = 0; i < contractNotes->count(); i++) {
					if (_matchfilter_chengjiaodan(f, contractNotes->data(contractNotes->idx_chengjiaodan_O60_O02()[i]))) {
						contractNotes->idx_filter_chengjiaodan_O60_O02()[j] = contractNotes->idx_chengjiaodan_O60_O02()[i];
						j++;
						contractNotes->iFilterCount() ++;
					}
				}
				for (int i = 0, j = 0; i < contractNotes->count(); i++) {
					if (_matchfilter_chengjiaodan(f, contractNotes->data(contractNotes->idx_chengjiaodan_O62()[i]))) {
						contractNotes->idx_filter_chengjiaodan_O62()[j] = contractNotes->idx_chengjiaodan_O62()[i];
						j++;
					}
				}
				contractNotes->_index_mutexs().unlock();
			}
		}
		contractNotes->mutex().unlock_shared();
		return 0;
	}
	else if (index == INDEX_JG_CHENGJIAODAN || index == INDEX_ZLC_CHENGJIAODAN) {
		deliveryContractNotes->mutex().lock_shared();
		lastDataLists[index].clear();
		lastIndex[index] = 0;

		SFILTER_JG_ZLC_CHENGJIAODAN* f = (SFILTER_JG_ZLC_CHENGJIAODAN*)data;
		SFILTER_JG_ZLC_CHENGJIAODAN* filter = index == INDEX_JG_CHENGJIAODAN ? &deliveryContractNotes->filter_jg_chengjiaodan() : &deliveryContractNotes->filter_zlc_chengjiaodan();
		// 注意这里对于交割、中立仓成交单的O05字段必须是固定不可以修改
		// 仅交割、中立仓成交单需要做强制更新时直接用内部filter变量作为参考
		if (f != filter && f->cI10 == filter->cI10 && f->iM20 == filter->iM20 && f->iM30 == filter->iM30){
			deliveryContractNotes->mutex().unlock_shared();
			return 0;
		}
		else {
            //TODO: differ  JG from  ZLC  in filter
			filter->cI10 = f->cI10;
			filter->iM20 = f->iM20;
			filter->iM30 = f->iM30;
			if (index == INDEX_JG_CHENGJIAODAN) {
				// 使用全量索引进行筛选判断直接生成筛选索引
				deliveryContractNotes->_index_mutexsDelivery().lock();
				deliveryContractNotes->iFilterCountDelivery() = 0;
				for (int i = 0, j = 0; i < deliveryContractNotes->count(); i++) {
					if (_matchfilter_jg_zlc_chengjiaodan(f, 
								deliveryContractNotes->data(deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i]))) {
						deliveryContractNotes->idx_filter_jg_chengjiaodan_O60_O02()[j] = deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i];
						deliveryContractNotes->idx_filter_jg_chengjiaodan_O62()[j] = deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i];  // 先根据O60_O02索引加入，后面再快速排序
						j++;
						deliveryContractNotes->iFilterCountDelivery() ++;
					}
				}
				// 交割、中立仓成交单共用内存数组，而且筛选是必然，所以没有必要维护公共的按时间排序索引，在设置时通过快速排序生成即可
				_quicksort(INDEX_JG_CHENGJIAODAN, deliveryContractNotes->idx_filter_jg_chengjiaodan_O62(), 0, deliveryContractNotes->iFilterCountDelivery() - 1, FIELD_JG_ZLC_CHENGJIAODAN_iO62_part);
				deliveryContractNotes->_index_mutexsDelivery().unlock();
			}
			else {
				// 使用全量索引进行筛选判断直接生成筛选索引
				deliveryContractNotes->_index_mutexsMiddle().lock();
				deliveryContractNotes->iFilterCountMiddle() = 0;
				for (int i = 0, j = 0; i < deliveryContractNotes->count(); i++) {
					if (_matchfilter_jg_zlc_chengjiaodan(f, 
								deliveryContractNotes->data(deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i]))) {
						deliveryContractNotes->idx_filter_zlc_chengjiaodan_O60_O02()[j] = deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i];
						deliveryContractNotes->idx_filter_zlc_chengjiaodan_O62()[j] = deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02()[i];  // 先根据O60_O02索引加入，后面再快速排序
						j++;
						deliveryContractNotes->iFilterCountMiddle() ++;
					}
				}
				_quicksort(INDEX_ZLC_CHENGJIAODAN, deliveryContractNotes->idx_filter_zlc_chengjiaodan_O62(), 0, deliveryContractNotes->iFilterCountMiddle() - 1, FIELD_JG_ZLC_CHENGJIAODAN_iO62_part);
				deliveryContractNotes->_index_mutexsMiddle().unlock();
			}
		}
		deliveryContractNotes->mutex().unlock_shared();
		return 0;
	}
	return 0;
}
// 获取数据
SCOUNT getData(int index, int field, bool asc, bool absolute, int m, int n, int* dataList) {
	int* idx = NULL; // 使用索引
	SCOUNT cnt;
	if (index == INDEX_BAODAN) {
		cnt.total = orders->bIsFiltered() ? orders->iFilterCount() : orders->count();
		if (field == FIELD_BAODAN_NONE)
			idx = orders->bIsFiltered() ? orders->idx_filter_baodan_O00() : orders->idx_baodan_O00();
		else
			idx = orders->bIsFiltered() ? orders->idx_filter_baodan_T12() : orders->idx_baodan_T12();
		if (orders->bIsFiltered())
			orders->_index_mutexs().lock();
	}
	else if (index == INDEX_JIAOGE) {
		cnt.total = deliveryOrders->bIsFiltered() ? deliveryOrders->iFilterCount() : deliveryOrders->count();
		if (field == FIELD_JIAOGE_NONE)
			idx = deliveryOrders->bIsFiltered() ? deliveryOrders->idx_filter_jiaoge_O00() : deliveryOrders->idx_jiaoge_O00();
		else
			idx = deliveryOrders->bIsFiltered() ? deliveryOrders->idx_filter_jiaoge_T12() : deliveryOrders->idx_jiaoge_T12();
		if (deliveryOrders->bIsFiltered())
			deliveryOrders->_index_mutexs().lock();
	}
	else if (index == INDEX_ZHONGLICANG) {
		cnt.total = middleOrders->bIsFiltered() ? middleOrders->iFilterCount() : middleOrders->count();
		if (field == FIELD_ZHONGLICANG_NONE)
			idx = middleOrders->bIsFiltered() ? middleOrders->idx_filter_zhonglicang_O00() : middleOrders->idx_zhonglicang_O00();
		else
			idx = middleOrders->bIsFiltered() ? middleOrders->idx_filter_zhonglicang_T12() : middleOrders->idx_zhonglicang_T12();
		if (middleOrders->bIsFiltered())
			middleOrders->_index_mutexs().lock();
	}
	else if (index == INDEX_CHENGJIAODAN) {
		cnt.total = contractNotes->bIsFiltered() ? contractNotes->iFilterCount() : contractNotes->count();
		if (field == FIELD_CHENGJIAODAN_NONE)
			idx = contractNotes->bIsFiltered() ? contractNotes->idx_filter_chengjiaodan_O60_O02() : contractNotes->idx_chengjiaodan_O60_O02();
		else
			idx = contractNotes->bIsFiltered() ? contractNotes->idx_filter_chengjiaodan_O62() : contractNotes->idx_chengjiaodan_O62();
		if (contractNotes->bIsFiltered())
			contractNotes->_index_mutexs().lock();
	}
	else if (index == INDEX_JG_CHENGJIAODAN) {
		cnt.total = deliveryContractNotes->iFilterCountDelivery();
		idx = field == FIELD_JG_ZLC_CHENGJIAODAN_NONE ? deliveryContractNotes->idx_filter_jg_chengjiaodan_O60_O02() : deliveryContractNotes->idx_filter_jg_chengjiaodan_O62();
		deliveryContractNotes->_index_mutexsDelivery().lock();
	}
	else if (index == INDEX_ZLC_CHENGJIAODAN) {
		cnt.total = deliveryContractNotes->iFilterCountMiddle();
		idx = field == FIELD_JG_ZLC_CHENGJIAODAN_NONE ? deliveryContractNotes->idx_filter_zlc_chengjiaodan_O60_O02() : deliveryContractNotes->idx_filter_zlc_chengjiaodan_O62();
		deliveryContractNotes->_index_mutexsMiddle().lock();
	}
	else if (index == INDEX_GONGGAO) {
		cnt.total = notices->count();
		idx = notices->idx_gonggao_T80();
	}
	else {
		cnt.total = -1;
		cnt.count = -1;
		return cnt;
	}
	if (!absolute) { // 相对位置，均第一条数据为基准，若该记录不存在则继续下一条
		unsigned long size = lastDataLists[index].size();
		for (int i = 0; i < size; i++) {
			int indexIdx = _binarysearch(index, cnt.total, idx, lastDataLists[index].at(i), NULL, field, MODE_NONE);
			if (indexIdx != NOT_FOUND) {
				cnt.index = (asc ? indexIdx : cnt.total - 1 - indexIdx) + m - i;
				break;
			}
			else if (i == size - 1)
				cnt.index = lastIndex[index] + m; // 如果所有数据都不在当前索引内，则用原有m值来处理
		}
	}
	else // 绝对位置时，如果为-1则显示尾部数据
		cnt.index = m < 0 ? cnt.total - n : m;
	// 这里防止数据越界
	if (cnt.index < 0)
		cnt.index = 0;
	m = cnt.index; // 这里将相对和绝对位置的序号重新以绝对方式赋给m
	lastIndex[index] = cnt.index;
	cnt.count = 0;
	if (asc) {
		for (; cnt.count < n && m + cnt.count < cnt.total; cnt.count++)
			dataList[cnt.count] = idx[m + cnt.count];
	}
	else {
		m = cnt.total - m - 1;
		for (; cnt.count < n && m - cnt.count >= 0; cnt.count++)
			dataList[cnt.count] = idx[m - cnt.count];
	}
	// 保存最近一次数据
	lastDataLists[index].clear();
	for (int i = 0; i < cnt.count; i++)
		lastDataLists[index].push_back(dataList[i]);

	// 解锁
    switch(index){
	    case INDEX_BAODAN :
		if (orders->bIsFiltered()){
			orders->_index_mutexs().unlock();
        }
        break;
        case INDEX_JIAOGE :
		if (deliveryOrders->bIsFiltered()){
			deliveryOrders->_index_mutexs().unlock(); 
        }
        break;
        case INDEX_ZHONGLICANG :
		if (middleOrders->bIsFiltered()){
			middleOrders->_index_mutexs().unlock();
        }
        break;
        case INDEX_CHENGJIAODAN:
		if (contractNotes->bIsFiltered()){
			contractNotes->_index_mutexs().unlock();
        }
	    case INDEX_JG_CHENGJIAODAN :
		    deliveryContractNotes->_index_mutexsDelivery().unlock();
            break;
        case INDEX_ZLC_CHENGJIAODAN:
            deliveryContractNotes->_index_mutexsMiddle().unlock();
            break;
        default:
            
        break;
    }
	return cnt;
}

//Next ???
// 查询数据
int queryData(int index, void* data, int field, int* dataList) {
	int count = 0;
	if (index == INDEX_BAODAN) {
		SQUERY_BAODAN* query = (SQUERY_BAODAN*)data;
		for (int i = 0; i < orders->count(); i++) {
			if (_matchquery_baodan(query, orders->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else if (index == INDEX_JIAOGE) {
		SQUERY_JIAOGE* query = (SQUERY_JIAOGE*)data;
		for (int i = 0; i < deliveryOrders->count(); i++) {
			if (_matchquery_jiaoge(query, deliveryOrders->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else if (index == INDEX_ZHONGLICANG) {
		SQUERY_ZHONGLICANG* query = (SQUERY_ZHONGLICANG*)data;
		for (int i = 0; i < middleOrders->count(); i++) {
			if (_matchquery_zhonglicang(query, middleOrders->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else if (index == INDEX_CHENGJIAODAN) {
		SQUERY_CHENGJIAODAN* query = (SQUERY_CHENGJIAODAN*)data;
		for (int i = 0; i < contractNotes->count(); i++) {
			if (_matchquery_chengjiaodan(query, contractNotes->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else if (index == INDEX_JG_CHENGJIAODAN || index == INDEX_ZLC_CHENGJIAODAN) {
		SQUERY_JG_ZLC_CHENGJIAODAN* query = (SQUERY_JG_ZLC_CHENGJIAODAN*)data;
		for (int i = 0; i < deliveryContractNotes->count(); i++) {
			if (_matchquery_jg_zlc_chengjiaodan(query, deliveryContractNotes->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else if (index == INDEX_GONGGAO) {
		SQUERY_GONGGAO* query = (SQUERY_GONGGAO*)data;
		for (int i = 0; i < notices->count(); i++) {
			if (_matchquery_gonggao(query, notices->data(i))) {
				dataList[count] = i;
				count++;
			}
		}
	}
	else
		return -1;
	_quicksort(index, dataList, 0, count - 1, field);
	return count;
}
// 按排序重新整理数据
int sortData(int index, int field, int* dataList, int count) {
	if (index == INDEX_BAODAN || index == INDEX_JIAOGE || index == INDEX_ZHONGLICANG || index == INDEX_CHENGJIAODAN || index == INDEX_JG_CHENGJIAODAN || index == INDEX_ZLC_CHENGJIAODAN || index == INDEX_GONGGAO) {
		_quicksort(index, dataList, 0, count - 1, field);
		return count;
	}
	return -1;
}
// 自动分页返回当页数据
int getPageData(int numberPerPage, int pageIndex, bool asc, int* dataList, int count, int* list) {
	int index = numberPerPage * pageIndex;
	int j = 0;
	if (asc) {
		for (; j < numberPerPage && index + j < count; j++)
			list[j] = dataList[index + j];
	}
	else {
		index = count - index - 1;
		for (; j < numberPerPage && index - j >= 0; j++)
			list[j] = dataList[index - j];
	}
	return j;
}


//  **********   load & save Files START *********
// 含异常处理的索引保存
static size_t _fwrite_index(int* idx, size_t count, FILE* f) {
	size_t offset = 0;
	do {
		size_t _count = fwrite(idx + offset, sizeof(int), count - offset, f);
		if (_count <= 0)
			return 0;
		offset = offset + _count;
	} while (offset < count);
	return count;
}
// 含异常处理的内存数组数据保存
static size_t _fwrite_data(int index, size_t size, FILE* f, int count) {
	size_t offset = 0;
	do {
		size_t _count = fwrite(dataPointer(index, offset), size, count - offset, f);
		if (_count <= 0)
			return 0;
		offset = offset + _count;
	} while (offset < count);
	return count;
}
// 含异常处理的索引读取
static size_t _fread_index(int* idx, size_t count, FILE* f) {
	size_t offset = 0;
	do {
		size_t _count = fread(idx + offset, sizeof(int), count - offset, f);
		if (_count <= 0)
			return 0;
		offset = offset + _count;
	} while (offset < count);
	return count;
}
// 含异常处理的内存数组数据读取
static size_t _fread_data(int index, size_t size, FILE* f, int count) {
	size_t offset = 0;
	do {
		size_t _count = fread(dataPointer(index, offset), size, count - offset, f);
		if (_count <= 0)
			return 0;
		offset = offset + _count;
	} while (offset < count);
	return count;
}
// 序列化到文件
int saveToFile(const char* path) {
	if (iLastMappingX05 == iX05)
		return iX05;
	orders->mutex().lock_shared();
	FILE* f = fopen(path, "wb");
	if (f == NULL) {
		logs(error_, "memorydata-savefile-文件打开失败！");
		orders->mutex().unlock_shared();
		return ERROR_OPEN_FILE;
	}
	// 保存已处理完整的X05
	_x05_mutex.lock(); // 这里对于读写X05做了锁，防止意外；但一定要在锁报单之后锁X05，防止死锁；
	if (fwrite(&iX05, sizeof(int), 1, f) == 0) {
		_x05_mutex.unlock();
		logs(error_, "memorydata-savefile-x05值保存失败！");
		fclose(f);
		orders->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	_x05_mutex.unlock();
	// 保存报单
	if (fwrite(&orders->count(), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-报单总量保存失败！");
		fclose(f);
		orders->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (orders->count() > 0) {
		if (_fwrite_data(INDEX_BAODAN, sizeof(SBAODAN), f, orders->count()) == 0) {
			logs(error_, "memorydata-savefile-报单数据保存失败！");
			fclose(f);
			orders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(orders->idx_baodan_O00(), orders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-报单的报单编号索引保存失败！");
			fclose(f);
			orders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(orders->idx_baodan_T12(), orders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-报单的申报时间索引保存失败！");
			fclose(f);
			orders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	orders->mutex().unlock_shared();
	// 保存交割单
	deliveryOrders->mutex().lock_shared();
	if (fwrite(&(deliveryOrders->count()), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-交割总量保存失败！");
		fclose(f);
		deliveryOrders->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (deliveryOrders->count() > 0) {
		if (_fwrite_data(INDEX_JIAOGE, sizeof(SJIAOGE), f, deliveryOrders->count()) == 0) {
			logs(error_, "memorydata-savefile-交割数据保存失败！");
			fclose(f);
			deliveryOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(deliveryOrders->idx_jiaoge_O00(), deliveryOrders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-交割的报单编号索引保存失败！");
			fclose(f);
			deliveryOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(deliveryOrders->idx_jiaoge_T12(), deliveryOrders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-交割的申报时间索引保存失败！");
			fclose(f);
			deliveryOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	deliveryOrders->mutex().unlock_shared();
	// 保存中立仓
	middleOrders->mutex().lock_shared();
	if (fwrite(&(middleOrders->count()), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-中立仓总量保存失败！");
		fclose(f);
		middleOrders->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (middleOrders->count() > 0) {
		if (_fwrite_data(INDEX_ZHONGLICANG, sizeof(SZHONGLICANG), f, middleOrders->count()) == 0) {
			logs(error_, "memorydata-savefile-中立仓数据保存失败！");
			fclose(f);
			middleOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(middleOrders->idx_zhonglicang_O00(), middleOrders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-中立仓的报单编号索引保存失败！");
			fclose(f);
			middleOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(middleOrders->idx_zhonglicang_T12(), middleOrders->count(), f) == 0) {
			logs(error_, "memorydata-savefile-中立仓的申报时间索引保存失败！");
			fclose(f);
			middleOrders->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	middleOrders->mutex().unlock_shared();
	// 保存成交单
	contractNotes->mutex().lock_shared();
	if (fwrite(&(contractNotes->count()), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-成交单总量保存失败！");
		fclose(f);
		contractNotes->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (contractNotes->count() > 0) {
		if (_fwrite_data(INDEX_CHENGJIAODAN, sizeof(SCHENGJIAODAN), f, contractNotes->count()) == 0) {
			logs(error_, "memorydata-savefile-成交单数据保存失败！");
			fclose(f);
			contractNotes->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(contractNotes->idx_chengjiaodan_O60_O02(), contractNotes->count(), f) == 0) {
			logs(error_, "memorydata-savefile-成交单成交编号索引保存失败！");
			fclose(f);
			contractNotes->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(contractNotes->idx_chengjiaodan_O62(), contractNotes->count(), f) == 0) {
			logs(error_, "memorydata-savefile-成交单成交时间保存失败！");
			fclose(f);
			contractNotes->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	contractNotes->mutex().unlock_shared();
	// 保存交割、中立仓成交单（注意两者共用同一内存区，为一个锁）
	deliveryContractNotes->mutex().lock_shared();
	if (fwrite(&(deliveryContractNotes->count()), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-交割成交总量保存失败！");
		fclose(f);
		deliveryContractNotes->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (deliveryContractNotes->count() > 0) {
		if (_fwrite_data(INDEX_JG_CHENGJIAODAN, sizeof(SJG_ZLC_CHENGJIAODAN), f, deliveryContractNotes->count()) == 0) {
			logs(error_, "memorydata-savefile-交割成交数据保存失败！");
			fclose(f);
			deliveryContractNotes->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02(), deliveryContractNotes->count(), f) == 0) {
			logs(error_, "memorydata-savefile-交割成交成交单编号索引保存失败！");
			fclose(f);
			deliveryContractNotes->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	deliveryContractNotes->mutex().unlock_shared();
	// 保存公告
	notices->mutex().lock_shared();
	if (fwrite(&(notices->count()), sizeof(int), 1, f) == 0) {
		logs(error_, "memorydata-savefile-公告总量保存失败！");
		fclose(f);
		notices->mutex().unlock_shared();
		return ERROR_FILE_WRITE;
	}
	if (notices->count() > 0) {
		if (_fwrite_data(INDEX_GONGGAO, sizeof(SGONGGAO), f, notices->count()) == 0) {
			logs(error_, "memorydata-savefile-公告数据保存失败！");
			fclose(f);
			notices->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
		if (_fwrite_index(notices->idx_gonggao_T80(), notices->count(), f) == 0) {
			logs(error_, "memorydata-savefile-公告索引保存失败！");
			fclose(f);
			notices->mutex().unlock_shared();
			return ERROR_FILE_WRITE;
		}
	}
	notices->mutex().unlock_shared();

	iLastMappingX05 = iX05;
	fclose(f);
	return iX05;
}
 int loadFromFile(const char* path) {
	__lock_exclude_all(); // 因为只有在登录阶段才使用该函数，所以无必要分开进行锁
	FILE* f = fopen(path, "rb");
	if (f == NULL){
		logs(error_, "open file error:" + std::string(path));
		__unlock_exclude_all();
		return ERROR_OPEN_FILE;
	}
	// 读取已处理完整的X05
	if (fread(&iX05, sizeof(int), 1, f) == 0)
		goto error_read;
	// 读取报单
	if (fread(&(orders->count()), sizeof(int), 1, f) == 0)
		goto error_read;
	if (orders->count() > 0) {
		if (_fread_data(INDEX_BAODAN, sizeof(SBAODAN), f, orders->count()) == 0)
			goto error_read;
		if (_fread_index(orders->idx_baodan_O00(), orders->count(), f) == 0)
			goto error_read;
		if (_fread_index(orders->idx_baodan_T12(), orders->count(), f) == 0)
			goto error_read;
	}
	// 读取交割单
	if (fread(&(deliveryOrders->count()), sizeof(int), 1, f) == 0)
		goto error_read;
	if (deliveryOrders->count() > 0) {
		if (_fread_data(INDEX_JIAOGE, sizeof(SJIAOGE), f, deliveryOrders->count()) == 0)
			goto error_read;
		if (_fread_index(deliveryOrders->idx_jiaoge_O00(), deliveryOrders->count(), f) == 0)
			goto error_read;
		if (_fread_index(deliveryOrders->idx_jiaoge_T12(), deliveryOrders->count(), f) == 0)
			goto error_read;
	}
	// 读取中立仓
	if (fread(&(middleOrders->count()), sizeof(int), 1, f) == 0)
		goto error_read;
	if (middleOrders->count() > 0) {
		if (_fread_data(INDEX_ZHONGLICANG, sizeof(SZHONGLICANG), f, middleOrders->count()) == 0)
			goto error_read;
		if (_fread_index(middleOrders->idx_zhonglicang_O00(), middleOrders->count(), f) == 0)
			goto error_read;
		if (_fread_index(middleOrders->idx_zhonglicang_T12(), middleOrders->count(), f) == 0)
			goto error_read;
	}
	// 读取成交单
	if (fread(&(contractNotes->count()), sizeof(int), 1, f) == 0)
		goto error_read;
	if (contractNotes->count() > 0) {
		if (_fread_data(INDEX_CHENGJIAODAN, sizeof(SCHENGJIAODAN), f, contractNotes->count()) == 0)
			goto error_read;
		if (_fread_index(contractNotes->idx_chengjiaodan_O60_O02(), contractNotes->count(), f) == 0)
			goto error_read;
		if (_fread_index(contractNotes->idx_chengjiaodan_O62(), contractNotes->count(), f) == 0)
			goto error_read;
	}
	// 读取交割、中立仓成交单
	if (fread(&(deliveryContractNotes->count()), sizeof(int), 1, f) == 0)
		goto error_read;
	if (deliveryContractNotes->count() > 0) {
		if (_fread_data(INDEX_JG_CHENGJIAODAN, sizeof(SJG_ZLC_CHENGJIAODAN), f, deliveryContractNotes->count()) == 0)
			goto error_read;
		if (_fread_index(deliveryContractNotes->idx_jg_zlc_chengjiaodan_O60_O02(), deliveryContractNotes->count(), f) == 0)
			goto error_read;
	}
	// 读取公告
	if (fread(&(notices->count()), sizeof(int), 1, f) == 0){
		goto error_read;
	}
	if (notices->count() > 0) {
		if (_fread_data(INDEX_GONGGAO, sizeof(SGONGGAO), f, notices->count()) == 0){
			goto error_read;
		}
		if (_fread_index(notices->idx_gonggao_T80(), notices->count(), f) == 0){
			goto error_read;
		}
		// 最后的数据，所以不需要再seek
	}
	fclose(f);
	iMax_X05 = iX05;
	iLastMappingX05 = iX05;

	__unlock_exclude_all(); // 注意这里先解锁、因为后面生成索引还要加锁

	setFilter(INDEX_JG_CHENGJIAODAN, &deliveryContractNotes->filter_jg_chengjiaodan()); // 强制生成索引
	setFilter(INDEX_ZLC_CHENGJIAODAN, &deliveryContractNotes->filter_zlc_chengjiaodan());  // 强制生成索引
	return iX05;
error_read:
	fclose(f);
	__unlock_exclude_all();
	return ERROR_FILE_READ;
}
//  **********   load & save Files END *********



}//namespace mem
